package com.baomidou.springmvc.controller;

import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.One;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.springmvc.common.config.DBTypeEnum;
import com.baomidou.springmvc.common.config.DbContextHolder;
import com.baomidou.springmvc.common.utils.HttpRequestUtils;
import com.baomidou.springmvc.common.utils.Json;
import com.baomidou.springmvc.common.utils.JsonUtil;
import com.baomidou.springmvc.common.utils.StringUtil;
import com.baomidou.springmvc.common.utils.Utils;
import com.baomidou.springmvc.interceptor.MethodLog;
import com.baomidou.springmvc.interceptor.SameUrlData;
import com.baomidou.springmvc.model.system.User;
import com.baomidou.springmvc.service.system.IUserService;
import com.baomidou.springmvc.task.DynamicTask;

import net.bull.javamelody.MonitoredWithSpring;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;





/**
 * 
 * @author hewei
 * @ClassName: UserController
 * @Copyright beauty_tech
 * @date 2018年2月4日 下午9:14:59
 * @description 增删改查演示
 */

@Controller
@RequestMapping("/user")
public class UserController extends BaseController {
	private static Logger log = Logger.getLogger(UserController.class);
	private final IUserService userService;
	@Autowired  
	private DynamicTask dynamicTask;  
	@Autowired
	public UserController(IUserService userService) {
		this.userService = userService;
	}


	@RequestMapping("/index")
	@ResponseBody
	@MonitoredWithSpring
	public Json index(HttpServletRequest request) {
		log.info("====================request.getContextPath()："+request.getContextPath());
		log.info("====================request.getRequestURI()："+request.getRequestURI());
		log.info("====================request.getServletPath()："+request.getServletPath());



		return JsonUtil.json("欢迎使用不悔搭建的系统，使用过程中遇到问题可以联系不悔qq:975945748");
	}

	@MethodLog(description="示例_批量添加")
	@GetMapping("/save")
	@ResponseBody

	public Json preSave() {


		for(int i = 0;i < 10;i++){
			User u = new User();
			u.setAge(i);
			u.setName("test"+i);
			userService.insert(u);

		}
		return JsonUtil.json("添加成功");
	}


	@MethodLog(description="示例_登录")
	@GetMapping("/login/{name}/{pwd}")
	@ResponseBody
	public Json login(@PathVariable String name,@PathVariable String pwd){

		Subject currentUser = SecurityUtils.getSubject();

		if (!currentUser.isAuthenticated()) {
			// 把用户名和密码封装为 UsernamePasswordToken 对象
			UsernamePasswordToken token = new UsernamePasswordToken(Utils.trim(name), Utils.trim(pwd));
			// rememberme
			//token.setRememberMe(true);
			try {
				// 执行登录. 
				currentUser.login(token);
			} 
			// ... catch more exceptions here (maybe custom ones specific to your application?
			// 所有认证时异常的父类. 
			catch (AuthenticationException ae) {
				//unexpected condition?  error?
				log.error("==============>登录失败："+ae.getMessage());
				return JsonUtil.json("登录失败");
			}
		}
		log.info("=====================登陆成功！");
		Session session = currentUser.getSession();
		session.setAttribute("userVo",currentUser );
		log.info("=============>"+session.getAttribute("userVo"));
		return JsonUtil.jsonSuccess("登录成功！");

	}

	/**
	 * 查询实例
	 * @description 
	 * @author hewei
	 * @title: selectById
	 * @date 2018年2月5日 上午10:10:22
	 * @param id
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws ClassNotFoundException Json
	 */

	@GetMapping(value = "/selectById/{id}")
	@ResponseBody
	@MethodLog(description="示例_多选择查询")
	public Json selectById( @PathVariable String id) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
		User u = (User)Class.forName("com.baomidou.springmvc.model.system.User").newInstance();
		DbContextHolder.setDbType(DBTypeEnum.two);
		List<User> list = null;
		//查询单个
		u =  userService.selectById(Utils.trim(id));
		//查询所有
		if("0".equals(id)){
			list = userService.selectList(null);
			return JsonUtil.json(true, "查询成功！", list);
		}
		//自定义条件查询
		//		userService.selectOne(new EntityWrapper<User>().where("name={0}  ", "jammey"));

		//分页

		/*Page<User> uPage = userService.selectPage(new Page<User>(0, 15));
		List<User> list2 = uPage.getRecords();*/

		return JsonUtil.json(true, "查询成功！", u);

	}


	/**
	 * 根据ID删除
	 * @description 测试事务是否回滚
	 * @author hewei
	 * @title: delete
	 * @date 2018年2月5日 上午10:12:44
	 * @param id
	 * @return Json
	 */
	@ResponseBody
	@GetMapping("/delete/{id}")
	@MethodLog(description="示例_根据ID删除")
	@Transactional
	public Json delete(@PathVariable Long id) {
		 boolean a = userService.deleteById(id);
		 a = false;
		 if(!a)
			 throw new RuntimeException("删除失败");
		 return JsonUtil.jsonSuccess("okay");
	}

	/**
	 * 
	 * @description 测试springmvc在使用@@PathVariable参数绑定传值的时候传入部分中文(eg:其他)的时候404，建议是如果一个接口中传入的中文过
	 * 多则推荐使用@RequestParam这种方式
	 * @author hewei
	 * @title: testBug
	 * @date 2018年2月15日 下午1:37:26
	 * @param str
	 * @return Json
	 */
	@ResponseBody
	@GetMapping("/testBug/{str}")
	@MethodLog(description="示例_测试springmvcbug")
	public Json testBug(@PathVariable String str){
		log.info("===================传入的值是："+str);
		return JsonUtil.json(true, "测试成功！", str);

	}
	/**
	 * 解决上述bug方法1，多个字段仍然以/分隔
	 */
	@ResponseBody
	@GetMapping("/solveBug1/**")
	@MethodLog(description="示例_解决springmvcbug")
	public Json solveBug1(HttpServletRequest request){
		String str = Utils.ISOToUTF8(Utils.extractPathFromPattern(request));
		String [] arr = str.split("/");
		Arrays.asList(arr).stream().forEach(x -> log.info("=============传入的值是"+x));
		return JsonUtil.json(true, "nice job", arr);

	}
	/**
	 * 解决上述bug方法2，违背了restful风格
	 */
	@ResponseBody
	@GetMapping("/solveBug2")
	@MethodLog(description="示例_解决springmvcbug")
	public Json solveBug2(@RequestParam("username") String username){
		return JsonUtil.json(true, "nice job", username);

	}
	/**
	 * bug2,传入多个小数点值的时候的bug，解决办法，在后面加一个静态字段(77.887773,76.887777/77.888777,98.u822222)
	 * @description 
	 * @author hewei
	 * @title: calculateDistance
	 * @date 2018年2月15日 下午4:01:59
	 * @param pom1
	 * @param pom2
	 * @return Json
	 */
	@RequestMapping("/calculateDistance/{pom1}/{pom2}/prettyGirl-HBB")
	@ResponseBody
	@MethodLog(description="货主_计算驾车距离")
	public Json calculateDistance(@PathVariable String pom1,@PathVariable String pom2){
		log.info("==================坐标一:"+pom1);
		log.info("==================坐标二:"+pom2);


		return JsonUtil.json(true, "查询成功！", pom1);

	}
	@RequestMapping("/noPerm")
	@MethodLog(description="示例_无权限")
	public String noPerm(Model model){

		return "/unauthorized";

	}
	@RequestMapping("/noPerm2Mobile")
	@MethodLog(description="示例_手机端无权限返回")
	@ResponseBody
	public Json noPerm2Mobile(){
		return JsonUtil.json("您无权限！");

	}
	@RequestMapping("/toNoPermUI")
	@MethodLog(description="示例_电脑端无权限返回")
	public String toNoPermUI(Model model){
		return "/noPerm";

	}
	@GetMapping("/changeCron")
	@MethodLog(description="任务_修改任务执行参数")
	@ResponseBody
	public Json changeCron(@RequestParam(name="cronStr", required = true) String cronStr){
		log.info("==============改变前的执行频率："+dynamicTask.getCron());
		dynamicTask.setCron(cronStr);
		log.info("==============改变后的执行频率："+dynamicTask.getCron());
		return JsonUtil.jsonSuccess("okay");

	}
	@GetMapping("/validateRepeatData/{data}")
	@MethodLog(description="验证表单重复提交")
	@ResponseBody
	@SameUrlData
	public Json validateRepeatData(@PathVariable String data){
		log.info("===========================提交的数据为"+data);
		return JsonUtil.jsonSuccess("okay");
		
	}
	@GetMapping("/repeat")
	@ResponseBody
	public Json repeat(){
		return JsonUtil.json("请勿重复支付！");
	}
	

}
